package com.gudogudo.battleworm.model {
	import com.gudogudo.battleworm.contact.ContactConfig;	
	
	import flash.display.*;
	import flash.utils.getQualifiedClassName;

	import org.puremvc.as3.patterns.proxy.Proxy;
	import Box2D.Dynamics.*;	
	import Box2D.Collision.Shapes.*;	

	import com.red.battleworm.AppMain;	
	import com.gudogudo.battleworm.map.Map;
	
	/**
	 * @author zhangs
	 */
	public class MapProxy extends Proxy {
//		private static const IMAGE_NAME : String = "image";
		private static const SPRITE_NAME : String = "ape";
		private static const RECTANGLE : String = "Rectangle";
		private static const CIRCLE : String = "Circle";
		private static const BIRTH : String = "BIRTH";
		public static const COLOR : uint = 0x000000;
		
		private var m_world:b2World;
		private var polygonDef:b2PolygonDef;
		private var circleDef : b2CircleDef;
		private var bodyDef:b2BodyDef;
		private var body:b2Body;
		private var map : Map;

		public function MapProxy(proxyName : String = null, data : Object = null) {
			super(proxyName, data);
			
			map = new Map();
		}
		
		public function init(m_world:b2World) : void {
			this.m_world = m_world;
			polygonDef = new b2PolygonDef();
			circleDef = new b2CircleDef();
			bodyDef = new b2BodyDef();

			var map_sprite : Sprite = Sprite(this.getData());
//			var image : DisplayObject = map.getChildByName(IMAGE_NAME);
			var sprite : Sprite = Sprite(map_sprite.getChildByName(SPRITE_NAME));
			var obj : DisplayObject;
			for (var i : uint = 0; i < sprite.numChildren; i++) {
				obj = sprite.getChildAt(i);
				add_ape_Particle(obj);
			}
			var width : Number = AppMain.stage.stageWidth;
			var height : Number = AppMain.stage.stageHeight;
			trace(width, height);
			var filter : b2FilterData = new b2FilterData();
			filter.groupIndex = ContactConfig.groupIndex_Bound;
			createRect(width/2, -20, width+80, 40, 0, 1, filter);
			createRect(width/2, height+20, width+80, 40, 0, 1, filter);
			createRect(-20, height/2, 40, height, 0, 1, filter);
			createRect(width+20, height/2, 40, height, 0, 1, filter);
			trace(this.getProxyName(), "init");
		}
		
		private function add_ape_Particle(obj : DisplayObject) : void {
			switch(getQualifiedClassName(obj)) {
				case RECTANGLE:
					var rotation : Number = obj.rotation / 180 * Math.PI;
//					var sin : Number = Math.abs(Math.sin(rotation));
//					var cos : Number = Math.abs(Math.cos(rotation));
//					var width : Number = Math.abs((obj.width * cos - obj.height * sin) / (cos * cos - sin * sin));
//					var height : Number = Math.abs((obj.width * sin - obj.height * cos) / (cos * cos - sin * sin));
					obj.rotation = 0;
					var width : Number = obj.width;
					var height : Number = obj.height;
					trace(obj.name);
					if(obj.name && obj.name.toUpperCase().indexOf(BIRTH) >= 0) {
						map.birth_array.push({x:obj.x, y:obj.y, width:width, height:height, rotation:rotation});
					} else {
						createRect(obj.x, obj.y, width, height, rotation);
					}
					break;
				case CIRCLE:
					createCircle(obj.x, obj.y, (obj.width+obj.height)/4);
					break;
				default:
					trace("Can't resolve a object in add_ape_Particle.");
			}
		}
		
		private function createRect(px:Number, py:Number, width:Number, height:Number, angle:Number=0, friction:Number=0.2, filter:b2FilterData=null) : void {
			bodyDef.position.Set(px/Box2DConfig.PHYSSCALE, py/Box2DConfig.PHYSSCALE);
			bodyDef.angle = angle;
			polygonDef.SetAsBox(width/Box2DConfig.PHYSSCALE/2, height/Box2DConfig.PHYSSCALE/2);
			polygonDef.friction = friction;
			polygonDef.density = 0;
			if (filter != null) {
				polygonDef.filter = filter;
			}
			body = m_world.CreateBody(bodyDef);
			body.CreateShape(polygonDef);
			body.SetMassFromShapes();
		}
		
		private function createCircle(px:Number, py:Number, radius:Number, friction:Number=1, filter:b2FilterData=null) : void {
			bodyDef.position.Set(px/Box2DConfig.PHYSSCALE, py/Box2DConfig.PHYSSCALE);
			circleDef.radius = radius/Box2DConfig.PHYSSCALE;
			circleDef.friction = friction;
			circleDef.density = 0;
			if (filter != null) {
				circleDef.filter = filter;
			}
			body = m_world.CreateBody(bodyDef);
			body.CreateShape(circleDef);
			body.SetMassFromShapes();
		}
		
		public function getMap() : Map {
			return map;
		}
	}
}
